#include "../include/nodearraycache.h"
#include "../include/macro_signal.h"

NodeArrayCache::NodeArrayCache():cache_of_file_tree()
{
	curr_index_of_file_list=0;
	cache_size_of_file_list=0;
	cache_of_file_list=NULL;
}

NodeArrayCache::NodeArrayCache(int32 cache_size_):cache_of_file_tree()
{
	curr_index_of_file_list=0;
	cache_size_of_file_list=cache_size_;
	cache_of_file_list=new NodeArrayCacheUnit[cache_size_of_file_list];
}

NodeArrayCache::~NodeArrayCache()
{
	delete[] cache_of_file_list;
	for(uint32 i=0;i<cache_of_file_tree.size();i++)
		delete cache_of_file_tree[i];
}

const NodeArray* NodeArrayCache::findNodeArray(const QString& path,uint32 flag)
{
	switch(flag)
	{
	case FILELIST_NODEARRAY:
		{
			int32 index_of_list=searchInFileListCache(path);
			if(index_of_list<0)
			{
				int32 index_of_tree=searchInFileTreeCache(path);
				if(index_of_tree<0)
					return NULL;
				else
					return getNodeArrayFromAnotherCache(index_of_tree,flag);
			}
			else
				return cache_of_file_list[index_of_list].node_array;
		}
	case FILETREE_NODEARRAY:
		{
			int32 index_of_tree=searchInFileTreeCache(path);
			if(index_of_tree<0)
			{
				int32 index_of_list=searchInFileListCache(path);
				if(index_of_list<0)
					return NULL;
				else
					return getNodeArrayFromAnotherCache(index_of_list,flag);
			}
			else
				return cache_of_file_tree[index_of_tree]->node_array;
		}
	default:
		return NULL;
	}
	return NULL;
}

void NodeArrayCache::cacheNewNodeArray(const NodeArray* node_array,uint32 flag)
{
	switch(flag)
	{
		case FILELIST_NODEARRAY:
			cacheFileListNodeArray(node_array);
			break;
		case FILETREE_NODEARRAY:
			cacheFileTreeNodeArray(node_array);
			break;
		default:
			;
	}
}

int32 NodeArrayCache::searchInFileListCache(const QString& path) const
{
	uint32 len=cache_of_file_list[cache_size_of_file_list-1].isNull()?curr_index_of_file_list:cache_size_of_file_list;
	for(uint32 i=0;i<len;i++)
			if(cache_of_file_list[i].path()==path)
				return i;
	return -1;
}

int32 NodeArrayCache::searchInFileTreeCache(const QString& path) const
{
	for(uint32 i=0;i<cache_of_file_tree.size();i++)
		if(cache_of_file_tree[i]->path()==path)
			return i;
	return -1;
}

void NodeArrayCache::cacheFileListNodeArray(const NodeArray* node_array)
{
	cache_of_file_list[curr_index_of_file_list].cacheThis(node_array);
	incCurrIndexOfFileList();
}

void NodeArrayCache::cacheFileTreeNodeArray(const NodeArray* node_array)
{
	for(uint32 i=0;i<cache_of_file_tree.size();i++)
		if(!cache_of_file_tree[i]->node_array->isRefed())
		{
			cache_of_file_tree[i]->cacheThis(node_array);
			return;
		}
	cache_of_file_tree.append(new NodeArrayCacheUnit(node_array));
}

const NodeArray* NodeArrayCache::getNodeArrayFromAnotherCache(int32 node_array_index,uint32 flag)
{
	NodeArray* node_array;
	switch(flag)
	{
		case FILELIST_NODEARRAY:
			node_array=new NodeArray(*cache_of_file_tree[node_array_index]->node_array);
			cacheFileListNodeArray(node_array);
			return node_array;
		case FILETREE_NODEARRAY:
			node_array=new NodeArray(*cache_of_file_list[node_array_index].node_array);
			cacheFileTreeNodeArray(node_array);
			return node_array;
		default:
			return NULL;
	}
	return NULL;
}